import Singleton from '../Base/Singleton'
interface IEventHandler {
    ctx?: any
    func: Function
}
export default class EventManager extends Singleton {
    private eventDic: Map<string, Array<IEventHandler>> = new Map()
    static get Instance() {
        return super.getInstance<EventManager>()
    }
    // bind event handler for event named eventName
    // some events has serveral event handler
    on(eventName: string, eventHander: Function, thisArg: any) {
        if (!this.eventDic.has(eventName)) {
            this.eventDic.set(eventName, [{ func: eventHander, ctx: thisArg }])
        } else {
            this.eventDic.get(eventName).push({ func: eventHander, ctx: thisArg })
        }
    }
    // off bind some event handler for event named eventName
    off(eventName: string, func: Function) {
        if (this.eventDic.has(eventName)) {
            const index = this.eventDic.get(eventName).findIndex(v => v.func == func)
            index > -1 && this.eventDic.get(eventName).splice(index, 1)
        }
    }
    // emit eventhandler, rest parameter are bind to argument
    emit(eventName: string, ...argument: unknown[]) {
        if (this.eventDic.has(eventName)) {
            const handlers = this.eventDic.get(eventName)
            handlers.forEach(funcConfig => {
                funcConfig.ctx ? funcConfig.func.call(funcConfig.ctx, ...argument) : funcConfig.func(...argument)
            })
        }
    }
    // clear all evnet
    clear() {
        this.eventDic.clear()
    }
}
